package com.javaweb.aspect;

import java.lang.reflect.Method;
import java.util.concurrent.TimeUnit;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

import com.javaweb.annotation.task.DistributedTimedTask;
import com.javaweb.base.BaseInject;
import com.javaweb.constant.SystemConstant.ScheduledTaskConstant;

/**
 * 分布式定时任务切面
 * <p>
 * 需要保证注解DistributedTimedTask的taskUniqueName不能重复，要唯一
 * @author tank2140896
 */
@Aspect
@Component
public class DistributedTimedTaskAspect extends BaseInject {
	
	/**
	 * 切面注解
	 * @param joinPoint ProceedingJoinPoint
	 * @see com.javaweb.annotation.task.DistributedTimedTask
	 */
	@Around(value=ScheduledTaskConstant.DEFAULT_DISTRIBUTED_TIMED_TASK_POINT_CUT)
	public void redisTryLock(ProceedingJoinPoint joinPoint) {
		try{
			Class<?> cls = joinPoint.getTarget().getClass();
			String name = joinPoint.getSignature().getName();
			Method method = cls.getMethod(name);
			DistributedTimedTask annotation = method.getAnnotation(DistributedTimedTask.class);
			String taskUniqueName = annotation.taskUniqueName();
			//防止锁不被释放，该值最好兼容多台服务器的时间差同时定时任务的执行频率不应该小于该值，一般认为多台服务器时间差最多为30秒
			Boolean flag = valueOperations.setIfAbsent(taskUniqueName,ScheduledTaskConstant.DISTRIBUTED_TIMED_TASK_KEY,30,TimeUnit.SECONDS);
			if(flag!=null&&flag) {
				log.info("当前服务器由于[有]获取到分布式锁，所以[需要]执行分布式定时任务（"+taskUniqueName+"）");
				joinPoint.proceed();
			}else {
				log.info("当前服务器由于[没有]获取到分布式锁，所以[无需]执行分布式定时任务（"+taskUniqueName+"）");
			}
		}catch(Throwable e) {
			log.error("执行分布式定时任务发生异常，异常信息为："+e.getMessage());
		}
	}
	
}
